DirectX:Direct3D:Tutorials:VBNET:DX9:Handling Device Loss
Handling Device Loss In Managed Direct3D When you make a fullscreen Direct3D game, your program takes exclusive control of the Device. Your game will lose exclusive control whenever your game loses focus. When your program tries to render as normal, it will throw an error message. In order to continue rendering, your device needs to be reset, and exclusive control needs to be regained. You'll need a boolean variable to keep track of whether or not the device is currently lost: Private DeviceLost As Boolean 'For handling device loss You need to check and see if the device is currently lost at the beginning of your render sub. It should look like this: Public Sub Render() 'check for device loss If DeviceLost Then AttemptRecovery() ' this is obvious, isn't it? End If If DeviceLost Then 'if device is still lost, then forget it for now 'if you want your program to do something while the device is lost, you can tell it here End If That will check and if the device is lost, then check to see if Attempt recovery worked. The second part is optional. Now, when you present your device, you need to handle DeviceLostException, which will be thrown if you don't have exclusive control. My code looks like this: Try graphicsdevice.Present() 'draw device contents to screen Catch e As DeviceLostException 'AAACK! We lost the device! DeviceLost = True End Try If you no longer have exclusive control, DeviceLost will be set to true; therefore your render sub will call the AttemptRecoverey subroutine the next time you try to render your graphics. Now let's look at AttemptRecoverey: Private Sub AttemptRecovery() ' when we lose the device, this code will run Try graphicsdevice.TestCooperativeLevel() 'Test for Exclusive control; if it's lacking, it'll throw Catch e As DeviceLostException 'DeviceLostException. If it does, we just wait until 'Failed. 'our game is given the focus again. Catch e As DeviceNotResetException 'If we have the focus, we only need to reset the device: ' Basically we re-do what we did in initialize graphics Try 'Here, you need to destroy everything in Pool_Default, and all instances of the ' swapchain class. graphicsdevice.Reset(presentParams) 'reset the device, so we can use it again DeviceLost = False 'device is no longer lost!!! 'Now recreate all your Pool_Default stuff, and your swapchain instances. Catch bug As DeviceLostException 'it is possible to lose the device while resetting it. 'if it got lost again or not reset, do nothing End Try End Try End Sub 'AttemptRecovery Looks nasty, but there's a reason for all that junk. First we test the cooperative level. If that throws Devicelostexception again, there’s no point in even trying to reset the device. If it throws DeviceNotReset, then we reset the device, and everything in Pool_Default. (This code was from a game that used only D3DX_Sprite objects, so nothing was destroyed and recreated). This is done by destroying the objects( setting them to nothing), and re-loading all the info. Sucks, huh? After we do all that, we check for deviceloss again just in case it died while we were resetting the device. It is hard to understand. I beat my head against it again and again before I managed to get it working. If you still have problems, check out the links on the bottom of this page, or ask around at the forums. I hope this very rough tutorial is of some help to somebody. Feel free to change it, or replace it with a superior one. --Lachlan87 15:46, 2 Dec 2004 (EST) =External Links= MSDN Article On Lost Devices DirectX4VB.com Blog On Lost Devices